gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdib/bmp.cpp

    /**********************************************************************
//
//
//        ##########                          ######  #########   # ######    #
//      #############                      ########### ######### #########  ###
//     ######## # ###  ##                 ############# ##    ## #####  # ####
//     ####  ##    ## ###                 ###     ### # #      #####   #####
//          #     ###  #            #     ##       ##  ##      ##     ###
//         ## ###### ##      ##  ####    ####          #       #     ##
//       #########  ###  ## ### #######   ######      ##      ##    ###
//      ######      ##  ######  ##  ##       ####     #      ##     ####
//     #######     ##   ###### ##  ###          ##   ##     ###    ######
//     #########   ##  ###### ## ######         ### ##    ###      #  #####
//    ##    ###### ####### ### #### ##  ## #######  ########      ##    ####
//    ##      #### ###  #  ### ### ##  ##########   ######       ##      ####
//   ##         ##                ##   #########    ####         #         ##
//               #              ###
//                              ##
//                             ###
//                             ##
//
//
//							RingSDK多媒体类库 ringdib.lib
//作者:临风
//
//版本:1.0
//
//声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到
//		  你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在
//		  修改的同时给作者一份同样的副本。
//		  本类库不得用于任何商业用途,如确实需要,请与作者联系。
//
//e-mail:ringphone@sina.com
//
//原文件名:bmp.cpp
//
//说明:BMP图象载入功能实现。
//
**********************************************************************/
#define MAKE_SELF_LIB
#include "ringdib.h"

BOOL RingDIB::LoadBmp(LPCTSTR szFilename,RingDIB* lprdib,int iFlag,LPSTR lpszFormat)
{
	if(iFlag == DIB_GETFORMAT)
	{
		if(lpszFormat)
		{
			wsprintf(lpszFormat,"bmp");
			return TRUE;
		}
		else
			return FALSE;
	}

	BITMAPFILEHEADER bmfh;
	BITMAPINFOHEADER bmih;
   HBITMAP hbm;
   BITMAP bm;
	ringFile rf;
	
	//BMP格式太多(颜色数,压缩不压缩,扫描行倒序不倒序),因此这里
	//直接调用API载入,懒得自己写解码了。
   if(szFilename && !IS_INTRESOURCE(szFilename))
	{
		if(rf.Open(szFilename) && rf.Read(&bmfh,sizeof(BITMAPFILEHEADER)) && 
			rf.Read(&bmih,sizeof(BITMAPINFOHEADER)))
		{
  	  		if(bmfh.bfType != 0x4D42 || iFlag == DIB_QUERYSUPPORT)
				return (BOOL)(bmfh.bfType == 0x4D42);
				
			lprdib->Create(bmih.biWidth,bmih.biHeight>0?bmih.biHeight:-bmih.biHeight);
			hbm = (HBITMAP)LoadImage(NULL,szFilename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
			if(hbm==NULL)
	   		return FALSE;
		}
		else
     		return FALSE;
   }
   else
   {
      hbm = LoadBitmap(GetInstance(),szFilename);

   	if(hbm==NULL)
     		return FALSE;
      GetObject(hbm,sizeof(BITMAP),&bm);
	   lprdib->Create(bm.bmWidth,bm.bmHeight);
   }

   lprdib->m_bmif.bmiHeader.biWidth = lprdib->m_width;
   lprdib->m_bmif.bmiHeader.biHeight = lprdib->m_height;

   HDC hDC = GetDC(lprdib->m_hWnd);
   GetDIBits(hDC,hbm,0,lprdib->m_height,lprdib->m_Bits,&lprdib->m_bmif,DIB_RGB_COLORS);
	ReleaseDC(lprdib->m_hWnd,hDC);

	lprdib->SetSrc(0,0);
	lprdib->SetDest(0,0);

   DeleteObject(hbm);

   return TRUE;
}

HBITMAP RingDIB::GetBitmap()
{
	if(m_Bits == NULL)
		return NULL;

	m_bmif.bmiHeader.biWidth=m_width;
   m_bmif.bmiHeader.biHeight=m_height;

	HDC hDC = GetDC(m_hWnd);
	HBITMAP hbm = CreateCompatibleBitmap(hDC,m_width,m_height);
	if(hbm)
		SetDIBits(hDC,hbm,0,m_height,m_Bits,&m_bmif,DIB_RGB_COLORS);
	
	ReleaseDC(m_hWnd,hDC);

	return hbm;
}

BOOL RingDIB::Import(HBITMAP hbm)
{
	BITMAP bm;

	if(hbm==NULL)
     	return FALSE;

   GetObject(hbm,sizeof(BITMAP),&bm);
	Create(bm.bmWidth,bm.bmHeight);
   
   m_bmif.bmiHeader.biWidth=m_width;
   m_bmif.bmiHeader.biHeight=m_height;

   HDC hDC = GetDC(m_hWnd);
   GetDIBits (hDC,hbm,0,m_height,m_Bits,&m_bmif,DIB_RGB_COLORS);
   ReleaseDC(m_hWnd,hDC);

	SetSrc(0,0);
   return TRUE;
}

BOOL SaveBMP(LPCTSTR szFilename,RingDIB* rdib)
{
	BITMAPFILEHEADER bmfh;
   BITMAPINFOHEADER bmih;
   ringFile rf = szFilename;
   LPBYTE lpb,lpd,lps;
   
   if(rdib == NULL)
      return FALSE;

	int w = rdib->Width(),h = rdib->Height();
   ZeroMemory(&bmfh,sizeof(BITMAPFILEHEADER));
   bmfh.bfType = 0x4d42;
	//cw必须是4的倍数((x+3)&0b1100[=0xC]为实现该功能的一个小小技巧)
	int cw = (int)(((w * 3) + 3) & 0xFFFFFFFC) ;

	bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + cw * h;
   bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

   if(!rf.Create(RF_NEW))
      return FALSE;

   if(!rf.Write(&bmfh,sizeof(BITMAPFILEHEADER),TRUE))
   {
      rf.Close();
      return FALSE;
   }

   ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER));
   bmih.biSize = sizeof(BITMAPINFOHEADER);
   bmih.biWidth = w;
   bmih.biHeight = h;
   bmih.biPlanes = 1;
   bmih.biBitCount = 24;
   bmih.biCompression = BI_RGB;

   if(!rf.Write(&bmih,sizeof(BITMAPINFOHEADER),TRUE))
      return FALSE;

   lpb = (LPBYTE)New(cw * h);
   if(lpb == NULL)
   {
      rf.Close();
      return FALSE;
   }

   lps = (LPBYTE)rdib->Data();
	lpd = lpb;

	if(lpd)
	{
//		   lpd = lpb + w * 3 * (h - 1);
//         int height_plus= w * 6;
      int n=0;   
		for(int j=0;j<h;j++)
		{
  			for(int i=0;i<w;i++)
			{
				lpd[0] = lps[0];
				lpd[1] = lps[1];
				lpd[2] = lps[2];
				lpd += 3;
				n++;
				lps += 4;
				if(n == 4)
					n = 0;
			}
			lpd += n;//lpb + j * cw;
			n = 0;
		}      
	}	
	
   if(!rf.Write(lpb,cw * h,TRUE))
   {
      Del(lpb);
      rf.Close();
      return FALSE;
   }

   Del(lpb);

   rf.Close();
   return TRUE;
}